package org.log4jeditor.xml.editor.quickfix;

import static org.junit.Assert.assertEquals;

import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.IMarkerResolution;
import org.junit.Assert;
import org.junit.Test;
import org.log4jconfig.xml.editor.quickfix.AllDeprecatedElementsReplaceQuickFix;
import org.log4jconfig.xml.editor.quickfix.AnyDeprecatedElementMarkerResolutionGenerator;
import org.log4jconfig.xml.editor.validation.ContentValidator;
import org.log4jeditor.xml.editor.AbstractUITestCase;
import org.log4jeditor.xml.editor.Log4jConfigXMLEditorTestsPlugin;
import org.log4jeditor.xml.editor.WorkbenchTasks;

public class AllDeprecatedElementsReplaceResolutionTestCase extends AbstractUITestCase {

	private ContentValidator validator;

	protected void setupWithFile(String filename) throws Exception {
		setupEditorConfiguration(filename);
		// remove all markers on document
		WorkbenchTasks.deleteAllMarkersOnFile(file);
		validator = new ContentValidator();
		validator.connect(document);
	}
	
	protected AllDeprecatedElementsReplaceQuickFix getQuickFix(int lineNumber, int columnNumber, String expectedNodeName) throws Exception {
		int offset = getDocumentOffset(lineNumber, columnNumber, expectedNodeName);
		validator.validate(getDirtyRegion(offset), null, null);
		assertEquals("Wrong number of markers:", 1, getMarkers().length);
		IMarker marker = getMarkers()[0];
		assertEquals("Wrong marker level:", IMarker.SEVERITY_WARNING, marker.getAttribute(IMarker.SEVERITY));
		AnyDeprecatedElementMarkerResolutionGenerator generator = new AnyDeprecatedElementMarkerResolutionGenerator();
		Assert.assertTrue(generator.hasResolutions(marker)); 
		IMarkerResolution[] resolutions  = generator.getResolutions(marker);
		Assert.assertTrue("Missing quickfix", resolutions .length >= 1);
		for(IMarkerResolution r : resolutions) {
			if(r.getClass().equals(AllDeprecatedElementsReplaceQuickFix.class)) {
				return (AllDeprecatedElementsReplaceQuickFix)r;
			}
		}
		Assert.fail("Missing quickfix");
		return null;
	}
	
	@Test
	public void testResolutionAttributes() throws Exception {
		setupWithFile("log4j-validation-category-priority.xml");
		AllDeprecatedElementsReplaceQuickFix quickFix = getQuickFix(21, 6, "category");
		Assert.assertNotNull("No label for custom quickfix", quickFix.getLabel());
		Assert.assertNotNull("No description for custom quickfix", quickFix.getDescription());
		Assert.assertNotNull("No image for custom quickfix", quickFix.getImage());
		Assert.assertNotNull("No image for custom quickfix", quickFix.getDisplayString());
		Assert.assertNull("Nothing expected here", quickFix.getAdditionalProposalInfo());
		Assert.assertNull("Nothing expected here", quickFix.getSelection(null));
		Assert.assertNull("Nothing expected here", quickFix.getContextInformation());
	}
	
	@Test
	public void testHasResolutionOKNone() throws Exception {
		setupWithFile("log4j-validation-category-priority.xml");
		int offset = getDocumentOffset(26, 21, "logger");
		validator.validate(getDirtyRegion(offset), null, null);
		assertEquals("Wrong number of markers:", 1, getMarkers().length);
		IMarker marker = getMarkers()[0];
		AnyDeprecatedElementMarkerResolutionGenerator generator = new AnyDeprecatedElementMarkerResolutionGenerator();
		Assert.assertFalse(generator.hasResolutions(marker));
	}

	@Test
	public void testHasResolutionKOExceptionNoMarkerExists() throws Exception {
		setupWithFile("log4j-validation-category-priority.xml");
		int offset = getDocumentOffset(26, 21, "logger");
		validator.validate(getDirtyRegion(offset), null, null);
		assertEquals("Wrong number of markers:", 1, getMarkers().length);
		IMarker marker = new IMarker() {

			public void delete() throws CoreException {
				
			}

			public boolean exists() {
				return false;
			}

			public Object getAttribute(String attributeName)
					throws CoreException {
				return null;
			}

			public int getAttribute(String attributeName, int defaultValue) {
				return 0;
			}

			public String getAttribute(String attributeName, String defaultValue) {
				return null;
			}

			public boolean getAttribute(String attributeName,
					boolean defaultValue) {
				return false;
			}

			@SuppressWarnings("unchecked")
			public Map getAttributes() throws CoreException {
				return null;
			}

			public Object[] getAttributes(String[] attributeNames)
					throws CoreException {
				return null;
			}

			public long getCreationTime() throws CoreException {
				return 0;
			}

			public long getId() {
				return 0;
			}

			public IResource getResource() {
				return null;
			}

			public String getType() throws CoreException {
				throw new CoreException(new Status(IStatus.ERROR, Log4jConfigXMLEditorTestsPlugin.PLUGIN_ID, "foo"));
			}

			public boolean isSubtypeOf(String superType) throws CoreException {
				return false;
			}

			public void setAttribute(String attributeName, int value)
					throws CoreException {
				
			}

			public void setAttribute(String attributeName, Object value)
					throws CoreException {
				
			}

			public void setAttribute(String attributeName, boolean value)
					throws CoreException {
				
			}

			@SuppressWarnings("unchecked")
			public void setAttributes(Map attributes) throws CoreException {
				
			}

			public void setAttributes(String[] attributeNames, Object[] values)
					throws CoreException {
				
			}

			@SuppressWarnings("unchecked")
			public Object getAdapter(Class adapter) {
				return null;
			}
			
		};
		
		AnyDeprecatedElementMarkerResolutionGenerator generator = new AnyDeprecatedElementMarkerResolutionGenerator();
		Assert.assertFalse(generator.hasResolutions(marker));
	}

	@Test
	public void testRun() throws Exception {
		setupWithFile("log4j-validation-category-priority-replaceAllDeprecatedElements.xml");
		getDocumentOffset(10, 6, "category");
		getDocumentOffset(11, 10, "priority");
		getDocumentOffset(12, 6, "category");
		getDocumentOffset(14, 6, "category");
		getDocumentOffset(15, 10, "priority");
		getDocumentOffset(16, 6, "category");
		getDocumentOffset(18, 6, "category");
		getDocumentOffset(21, 10, "priority");
		getQuickFix(18, 6, "category").run(getMarkers()[0]);
		getDocumentOffset(10, 6, "logger");
		getDocumentOffset(11, 10, "level");
		getDocumentOffset(12, 6, "logger");
		getDocumentOffset(14, 6, "logger");
		getDocumentOffset(15, 10, "level");
		getDocumentOffset(16, 6, "logger");
		getDocumentOffset(18, 6, "logger");
		getDocumentOffset(21, 10, "level");
		
	}

	@Test
	public void testApply() throws Exception {
		setupWithFile("log4j-validation-category-priority-replaceAllDeprecatedElements.xml");
		getDocumentOffset(10, 6, "category");
		getDocumentOffset(11, 10, "priority");
		getDocumentOffset(12, 6, "category");
		getDocumentOffset(14, 6, "category");
		getDocumentOffset(15, 10, "priority");
		getDocumentOffset(16, 6, "category");
		getDocumentOffset(18, 6, "category");
		getDocumentOffset(21, 10, "priority");
		getQuickFix(18, 6, "category").apply(document);
		getDocumentOffset(10, 6, "logger");
		getDocumentOffset(11, 10, "level");
		getDocumentOffset(12, 6, "logger");
		getDocumentOffset(14, 6, "logger");
		getDocumentOffset(15, 10, "level");
		getDocumentOffset(16, 6, "logger");
		getDocumentOffset(18, 6, "logger");
		getDocumentOffset(21, 10, "level");
		
	}
	

}
